package deployr.core;

import java.text.*;
import java.util.*;

public class Dates {

	private static final String MMMdyyyy = "MMM d, yyyy";

	private static final String MMMdyyyyHHmma = "MMM d, yyyy - HH:mm a";

	private static final String MMMdyyyyHHmmssa = "MMM d, yyyy - HH:mm:ss a";

	private static final String MMddyyyyHHmmss = "MMddyyyyHHmmss";

	private static String format(Date date, String pattern) {
		String previousResult = null;
		previousResult = tryFormat(date, using(pattern), orUse(previousResult));
		if (previousResult == null) throw new RuntimeException("unable to parse " + date);
		return previousResult;
	}

	public static final String formatMMMdyyyy(Date date) {
		return format(date, MMMdyyyy);
	}

	public static final String formatMMMdyyyyHHmma(Date date) {
		return format(date, MMMdyyyyHHmma);
	}

	public static final String formatMMMdyyyyHHmmssa(Date date) {
		return format(date, MMMdyyyyHHmmssa);
	}

	public static final String formatMMddyyyyHHmmss(Date date) {
		return format(date, MMddyyyyHHmmss);
	}

	public static final Date now() {
		return new Date();
	}

	private static <T> T orUse(T t) {
		return t;
	}

	private static Date parse(String formattedDate, String pattern) {
		Date previousResult = null;
		previousResult = tryParse(formattedDate, using(pattern), orUse(previousResult));
		if (previousResult == null) throw new RuntimeException("unable to parse " + formattedDate);
		return previousResult;
	}

	public static final Date parseMMMdyyyy(String formattedDate) {
		return parse(formattedDate, MMMdyyyy);
	}

	public static final Date parseMMMdyyyyHHmma(String formattedDate) {
		return parse(formattedDate, MMMdyyyyHHmma);
	}

	public static final Date parseMMMdyyyyHHmmssa(String formattedDate) {
		return parse(formattedDate, MMMdyyyyHHmmssa);
	}

	public static final Date parseMMddyyyyHHmmss(String formattedDate) {
		return parse(formattedDate, MMddyyyyHHmmss);
	}

	private static String tryFormat(Date date, String pattern, String previousFormattedDate) {
		if (previousFormattedDate != null) return previousFormattedDate;
		try {
			return new SimpleDateFormat(pattern, Locale.ENGLISH).format(date);
		} catch (Exception e) {
			return previousFormattedDate;
		}
	}

	private static Date tryParse(String formattedDate, String pattern, Date previousParsedDate) {
		if (previousParsedDate != null) return previousParsedDate;
		try {
			return new SimpleDateFormat(pattern, Locale.ENGLISH).parse(formattedDate);
		} catch (Exception e) {
			return previousParsedDate;
		}
	}

	private static String using(String string) {
		return string;
	}
}